package kz.pompei.oneGwtStands.client.remote.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import kz.pompei.OneGwt.cmodel.PersonDetails;
import kz.pompei.OneGwt.cmodel.PersonRecord;
import kz.pompei.OneGwt.cmodel.SimpleRecord;
import kz.pompei.OneGwt.remote.PersonroleManagerService;

public class PersonroleManagerServiceData implements PersonroleManagerService {
  private PersonroleManagerServiceData() {
    initSomePersons();
    initSomeApplications();
  }
  
  private final Map<String, PersonEntity> persons = new HashMap<String, PersonEntity>();
  private final Map<String, ApplicationEntity> applications = new HashMap<String, ApplicationEntity>();
  
  private int nextId = 1;
  
  private void initSomeApplications() {
    for (int i = 0; i < 10; i++) {
      ApplicationEntity x = new ApplicationEntity();
      {
        x.setId( "A" + nextId++ );
        x.setCode( "APP" + x.getId() );
        x.setName( "АИС " + x.getCode() );
        x.setVendor( "greetgo!" );
        for (int j = 0; j < 5; j++) {
          RoleEntity r = new RoleEntity();
          {
            r.setId( "R" + nextId++ );
            r.setCode( "CODE" + r.getId() );
            r.setName( "Роль " + r.getId() + " (" + x.getCode() + ")" );
          }
          x.getRoles().add( r );
          
          if (j == 0) {
            for (PersonEntity p : persons.values()) {
              p.getRoleIds().add( r.getId() );
            }
          }
        }
      }
      applications.put( x.getId(), x );
    }
  }
  
  private void initSomePersons() {
    for (int i = 0; i < 10; i++) {
      PersonEntity p = new PersonEntity();
      {
        p.setId( "P" + nextId++ );
        p.setAccountId( "ivanov" + p.getId() );
        p.setSurname( "Иванов" + p.getId() );
        p.setName( "Иван" + p.getId() );
        p.setPatronymic( "Иванович" + p.getId() );
      }
      persons.put( p.getId(), p );
    }
  }
  
  private static PersonroleManagerServiceData instance = null;
  
  public static PersonroleManagerServiceData get() {
    if (instance == null) instance = new PersonroleManagerServiceData();
    return instance;
  }
  
  @Override
  public List<PersonRecord> getPersonList() {
    List<PersonRecord> ret = new ArrayList<PersonRecord>();
    
    for (PersonEntity p : persons.values()) {
      if (p.isDeleted()) continue;
      ret.add( p.toRecord() );
    }
    
    return ret;
  }
  
  @Override
  public PersonDetails getPersonDetails(String personId) {
    PersonEntity p = persons.get( personId );
    if (p == null) return null;
    return p.toDetails();
  }
  
  @Override
  public PersonRecord savePerson(PersonDetails details) {
    if (details.getId() == null) {
      PersonEntity p = new PersonEntity();
      p.setId( "N" + nextId++ );
      apply( p, details );
      persons.put( p.getId(), p );
      return p.toRecord();
    }
    
    PersonEntity p = persons.get( details.getId() );
    apply( p, details );
    return p.toRecord();
  }
  
  private void apply(PersonEntity p, PersonDetails details) {
    p.setSurname( details.getSurname() );
    p.setName( details.getName() );
    p.setPatronymic( "no" );
    p.setAccountId( details.getAccountId() );
    p.setActive( details.isActive() );
  }
  
  @Override
  public List<SimpleRecord> getApplicationList() {
    List<SimpleRecord> ret = new ArrayList<SimpleRecord>();
    for (ApplicationEntity e : applications.values()) {
      ret.add( e.toSimpleRecord() );
    }
    return ret;
  }
  
  @Override
  public List<SimpleRecord> getRoleList(String applicationId) {
    List<SimpleRecord> ret = new ArrayList<SimpleRecord>();
    for (RoleEntity r : applications.get( applicationId ).getRoles()) {
      ret.add( r.toSimpleRecord() );
    }
    return ret;
  }
  
  @Override
  public Set<String> getRoleIds(String personId, String applicationId) {
    Set<String> ret = new HashSet<String>();
    Set<String> personRoleIds = persons.get( personId ).getRoleIds();
    for (RoleEntity r : applications.get( applicationId ).getRoles()) {
      if (personRoleIds.contains( r.getId() )) {
        ret.add( r.getId() );
      }
    }
    return ret;
  }
  
  @Override
  public void addRole(String personId, String applicationId, String roleId) {
    persons.get( personId ).getRoleIds().add( roleId );
  }
  
  @Override
  public void deleteRole(String personId, String applicationId, String roleId) {
    persons.get( personId ).getRoleIds().remove( roleId );
  }
}
